package com.vo;

import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.protocol.Packet;
import com.corundumstudio.socketio.protocol.PacketType;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;

import java.util.UUID;
import java.util.concurrent.ConcurrentLinkedDeque;

/**
 * Created by 石头哥哥 on 8/19/16.
 * PACKAGE_NAME:  controller
 * COMMENT :
 */
public class PlayerInstance {

    /**
     * 对象编号
     */
    private int ID;
    /**
     * 对象名**
     */
    private String name;

    /**
     * channel  netty
     */
    private Channel channel;

    /**
     * cache buffers
     */
    private ConcurrentLinkedDeque<ByteBuf> messageQueue
            = new ConcurrentLinkedDeque<ByteBuf>();

    private SocketIOClient socketIOClient;

    private UUID sessionID;
    private String eventName;

    public PlayerInstance() {
    }

    public PlayerInstance(SocketIOClient socketIOClient, UUID sessionID, String eventName) {
        this.socketIOClient = socketIOClient;
        this.sessionID = sessionID;
        this.eventName = eventName;
    }


    public SocketIOClient getSocketIOClient() {
        return socketIOClient;
    }

    public UUID getSessionID() {
        return sessionID;
    }


    /**
     *
     */
    @SuppressWarnings("Duplicates")
    public final void send(final ByteBuf buffer) {
        Packet packet = new Packet(PacketType.MESSAGE);
        packet.setSubType(PacketType.EVENT);
        packet.setName(eventName);
        packet.setData(buffer);
        socketIOClient.send(packet);
    }


    /**
     * @param buffer
     */
    public final void directSend(final ByteBuf buffer) {
        if (messageQueue == null) {   // this session is idvidle
            buffer.release();
            return;
        }
        messageQueue.addLast(buffer);// add tail
        //have data and channel is writable
        while (this.messageQueue.size() != 0
                && this.channel.isWritable()) {        // false , message will be queued
            this.channel.writeAndFlush(messageQueue.pollFirst()); //encode completed
        }
        // false , the message queued in app cache
    }


    /**
     * release
     */
    public void releaseBufs() {
        //clear bytebuf in queue
        if (messageQueue.size() != 0) {
            for (ByteBuf byteBuf : messageQueue) {
                // only if the reference count became {@code 0}
                // and this object has been deallocated
                byteBuf.release();
            }
            messageQueue.clear();
        }
        // for gc
        messageQueue = null; // had done
        channel = null;
    }

    public int getID() {
        return ID;
    }

    public void setID(int ID) {
        this.ID = ID;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Channel getChannel() {
        return channel;
    }

    public void setChannel(Channel channel) {
        this.channel = channel;
    }
}
